library(tidyverse)     # for graphing and data cleaning
## ── Attaching packages ─────────────────────────────────────── tidyverse 1.3.1 ──
## ✓ ggplot2 3.3.5     ✓ purrr   0.3.4
## ✓ tibble  3.1.6     ✓ dplyr   1.0.8
## ✓ tidyr   1.1.4     ✓ stringr 1.4.0
## ✓ readr   2.1.1     ✓ forcats 0.5.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## x dplyr::filter() masks stats::filter()
## x dplyr::lag()    masks stats::lag()
library(lubridate)     # for date manipulation
## 
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
## 
##     date, intersect, setdiff, union
library(ggthemes)      # for even more plotting themes
library(gganimate)     # for adding animation layers to ggplots
library(RColorBrewer)  # for color palettes
library(viridis)
## Loading required package: viridisLite
library(plotly)        # for the ggplotly() - basic interactivity
## 
## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2':
## 
##     last_plot
## The following object is masked from 'package:stats':
## 
##     filter
## The following object is masked from 'package:graphics':
## 
##     layout
library(gganimate)     # for adding animation layers to ggplots
library(transformr)    # for "tweening" (gganimate)
library(gifski)        # need the library for creating gifs but don't need to load each time
library(gt)
theme_set(theme_minimal()) # My favorite ggplot() theme :)
freq_theme_words <- read.csv("https://raw.githubusercontent.com/the-pudding/data/master/women-in-headlines/word_themes_freq.csv")
freq_country_words <- read.csv("https://raw.githubusercontent.com/the-pudding/data/master/women-in-headlines/word_country_freq.csv")
headline_site <- read.csv("https://raw.githubusercontent.com/the-pudding/data/master/women-in-headlines/headlines_site.csv")
word_theme_rank <- read.csv("https://raw.githubusercontent.com/the-pudding/data/master/women-in-headlines/word_themes_rank.csv")
headline_examples <- read.csv("https://raw.githubusercontent.com/the-pudding/data/master/women-in-headlines/headlines.csv")
polarity_site <- read.csv("https://raw.githubusercontent.com/the-pudding/data/master/women-in-headlines/polarity_comparison_site_country_time.csv")
polarity_over_time <- read.csv("https://raw.githubusercontent.com/the-pudding/data/master/women-in-headlines/polarity_comparison_country_time.csv")

POLARITY CALCULATIONS We measure polarity by performing sentiment analysis on each headline using the Vader python package, where each headline gets a sentiment score from -1 to 1 (from more negative to more positive). Because we are interested in polarity, we take the absolute value of each headline’s score.

BIAS CALCULATIONS We measure gender bias by tracking the combined occurrence of gendered language and social stereotypes usually associated with women. We do this in two steps: 1) We check if a headline contains gendered language (i.e. “spokeswoman,” “chairwoman,” “she,” “her,” “bride,” “daughter,” “daughters,” “female,” “fiancee,” “girl,” “girlfriend” etc.). 2) If it contains gendered language, we then count the number of words that are considered to be social stereotypes about women (i.e. “weak,” “modest,” “virgin,” “slut,” “whore,” “sexy,” “feminine,” “sensitive,” “emotional,” “gentle,” “soft,” “pretty,” “bitch,” “sexual” etc.). Finally, we normalize this count for all headlines within each outlet as a score between 0 and 1, and we aggregate (i.e. average) this score for each outlet. (site from pudding https://pudding.cool/2022/02/women-in-headlines/)

A cumulative bar graph for the words used to describe women used in headlines. They are divided into 5 main categories with crime and violence having the most words and the highest frequency. The graph is interactive so each word can be highlighted with the individual word and frequency.

pivot_words <- freq_theme_words %>% 
  pivot_longer(cols = -theme,
               names_to = "word",
               values_to = "freq") %>% 
  na.omit()

word_plot <- pivot_words %>% 
  filter(theme != "No theme") %>% 
  ggplot(aes(x = theme, 
             y = freq, 
             fill = fct_reorder(word, freq),
             text = paste("word:", word))) +
    geom_col(color = "black") +
    theme(legend.position = "none") +
    scale_fill_viridis_d()+
    labs(title = "Cumulative Frequency of Words describing Women in Headlines",
       x = "",
       y = "Frequency")

ggplotly(word_plot,
         tooltip = c("y", "text"))
pivot_country_word <- freq_country_words %>% 
  pivot_longer(cols = -country,
               names_to = "word",
               values_to = "number") %>% 
  filter(word != "X") %>% 
  na.omit()

pivot_country_word
word_theme_rank %>% 
  filter(`rank` < 6) %>% 
  select(!`X`) %>% 
  ggplot(aes(y = word, x = count)) +
  geom_col(aes(fill = count))+
  scale_fill_viridis_c(option = "viridis") +
  facet_wrap(~theme,
            scales = "free")+
  theme(legend.position = "none")+
  labs(title = "Count of Top 5 words per Theme",
       y = "",
       x = "")

Smooth line graph displaying the average polarity of headlines over time with the value from 2020 being displayed with a data point. Want to place top label above line but need to expand boundries of graph! Would like to animate over time, if we have time.

polarity_over_time %>% 
  group_by(`year`) %>% 
  summarise(women_mean = mean(`women_polarity_mean`),
            all_mean = mean(`all_polarity_mean`),
            year) %>% 
  ggplot()+
  geom_smooth(aes(x=`year`, y=`women_mean`), color = "springgreen4", se = FALSE)+
  geom_smooth(aes(x=`year`, y=`all_mean`), color = "black", se = FALSE)+
  geom_point(aes(x=2020.0, y=0.425), 
             color = "black", fill = "springgreen4", 
             size = 5, stroke = 2, shape = 21) +
  geom_point(aes(x=2020.0, y=0.28), size = 2.5)+
  geom_label(label = "Headlines about\nwomen", x= 2019.4, y=0.40, color = "springgreen4")+
  geom_label(label = "Headlines about\nother topics", x=2019.4, y= 0.25)+
  scale_x_continuous(breaks = c(2010, 2012, 2014, 2016, 2018, 2020))+
  labs(title = "Average of Polarity of News Headlines over Time",
       y = "",
       x = "")+
  theme(plot.title = element_text(hjust = 0.5),
        panel.grid.major.x = element_blank(),
        panel.grid.minor.x = element_blank(),
        panel.grid.major.y = element_blank(),
        panel.grid.minor.y = element_blank(),
        axis.line.x = element_line(color = "black"))
## `summarise()` has grouped output by 'year'. You can override using the
## `.groups` argument.
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'

Polarity from sites, base polarity (black) to women polarity (green) with the differences as a line segment, they are ordered by polarity of women value, not by differences

polarity_site %>% 
  ggplot()+
  geom_segment(aes(x=polarity_base, xend=polarity_women, y=fct_reorder(site, polarity_women), yend=site, color = country_of_pub), size = 1)+
  scale_color_manual(values = c("India" = "purple4",
                    "South Africa" = "thistle3",
                    "UK" = "steelblue4",
                    "USA" = "mediumseagreen"))+
  geom_point(aes(x=polarity_base, y = site), size = 2)+
  geom_point(aes(x=polarity_women, y = site), color = "black", fill = "springgreen4", 
             size = 3, stroke = 1, shape = 21)+
  labs(title = "Polarity of News Outlines:\n Headlines about Women vs. Headlines about other topics",
       y = "",
       x = "Polarity",
       color = "Country of\nPublication")+
  theme(plot.title = element_text(hjust = 0.5))

Ten example headlines from 10 different news sites, sorted by lowest bias score

last_ten_headlines <- headline_examples %>% 
  rename("Headline" = `headline_no_site`,
         "Site" = `site`,
         "Country" = `country`,
         "Bias" = `bias`) %>%
  arrange(`Bias`) %>%
  distinct(Site, .keep_all = TRUE) %>% 
  slice(1:10) %>% 
  select(`Headline`, `Site`, `Country`, `Bias`)

last_ten_headlines_table <- gt(last_ten_headlines) %>% 
  tab_header(title = "Least Biased Headline Examples") %>% 
  data_color(columns = vars(`Headline`, `Site`, `Country`, `Bias`), 
             colors = '#bccae0')
## Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
## * please use `columns = c(...)` instead
last_ten_headlines_table
Least Biased Headline Examples
Headline Site Country Bias
'Lady Bird' buzzes through young sexuality iol.co.za South Africa 0
American Woman, Divorced From Saudi Husband, Is Trapped in Saudi Arabia msn.com India 0
'SA poorer without her' SACP reacts to Madikizela Mandela's death News24.com South Africa 0
WATCH | North West farmer 'assaults man and mother' with knobkierie Sowetanlive.co.za South Africa 0
First look at Kim Kardashian and Kanye West's baby girl, Chicago Timeslive.co.za South Africa 0
Carly Fiorina Repeats After Girl: 'Donald Trump's a Moron' abcnews.go.com USA 0
KPMG's US CEO Lynne Doughtie explains why feeling uncomfortable in your job is actually a good thing businessinsider.com India 0
This Artist Makes Insanely Accurate Knitted People buzzfeed.com UK 0
University of Missouri professor ​Melissa Click: Video "doesn't represent the good I was doing" cbsnews.com USA 0
Jury convicts gang member in 2011 murder of pregnant teen chicagotribune.com USA 0

Ten example headlines from 10 different news sites, sorted by highest bias score

top_ten_headlines <- headline_examples %>% 
  rename("Headline" = `headline_no_site`,
         "Site" = `site`,
         "Country" = `country`) %>% 
  mutate(Bias = round(bias, digits = 3)) %>% 
  arrange(desc(`Bias`)) %>%
  distinct(Site, .keep_all = TRUE) %>% 
  slice(1:10) %>% 
  select(`Headline`, `Site`, `Country`, `Bias`)

top_ten_headlines_table <- gt(top_ten_headlines) %>% 
  tab_header(title = "Most Biased Headline Examples") %>% 
  data_color(columns = vars(`Headline`, `Site`, `Country`, `Bias`), 
             colors = '#bccae0')
## Warning: `columns = vars(...)` has been deprecated in gt 0.3.0:
## * please use `columns = c(...)` instead
top_ten_headlines_table
Most Biased Headline Examples
Headline Site Country Bias
Girl with severe eczema told her mum she 'didn't want to look at herself in the mirror' she's now a model manchestereveningnews.co.uk UK 1.000
A Mother Said Her 9 Year Old Daughter Killed Herself Because She Was Bullied For Being Friends With A White Boy buzzfeed.com UK 0.833
Wuthering Heights actress Merle Oberon's secret that she took to the grave... her sister was her mother who ga dailymail.co.uk India 0.833
Woman reunited with her long lost brother reveals surprise as she discovers she's now her SISTER dailyrecord.co.uk UK 0.833
Gal Gadot’s Daughter Made Wonder Woman Actress Appreciate the Importance of Female Superheroes hollywoodreporter.com USA 0.833
Priyanka Chopra's Mother Reveals She Got Emotional Seeing Her Daughter Dressed up as Bride india.com India 0.833
‘Why is there no Disney princess from India?’: Girl asks her mom and here’s what she does next indianexpress.com India 0.833
Woman regrets bum tattoo that reminds her of the time she defecated on herself beside boyfriend's mum mirror.co.uk UK 0.833
Lady Gaga's mom missed 'warning signs' of her daughter in 'crisis': 'For me, that’s a hard pill to still live with and swallow' news.yahoo.com India 0.833
Brooklyn woman whose mom died after she beat her up amid fight over cat suffers PTSD from life as prostitute nydailynews.com USA 0.833
LS0tCnRpdGxlOiAiSGVhZGxpbmVzIgphdXRob3I6ICJBdWRyZXkgU215Y3playIKZGF0ZTogIjQvMTQvMjAyMiIKb3V0cHV0OiAKICBodG1sX2RvY3VtZW50OgogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCi0tLQoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CiNrbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpCmBgYAoKYGBge3IgbGlicmFyaWVzfQpsaWJyYXJ5KHRpZHl2ZXJzZSkgICAgICMgZm9yIGdyYXBoaW5nIGFuZCBkYXRhIGNsZWFuaW5nCmxpYnJhcnkobHVicmlkYXRlKSAgICAgIyBmb3IgZGF0ZSBtYW5pcHVsYXRpb24KbGlicmFyeShnZ3RoZW1lcykgICAgICAjIGZvciBldmVuIG1vcmUgcGxvdHRpbmcgdGhlbWVzCmxpYnJhcnkoZ2dhbmltYXRlKSAgICAgIyBmb3IgYWRkaW5nIGFuaW1hdGlvbiBsYXllcnMgdG8gZ2dwbG90cwpsaWJyYXJ5KFJDb2xvckJyZXdlcikgICMgZm9yIGNvbG9yIHBhbGV0dGVzCmxpYnJhcnkodmlyaWRpcykKbGlicmFyeShwbG90bHkpICAgICAgICAjIGZvciB0aGUgZ2dwbG90bHkoKSAtIGJhc2ljIGludGVyYWN0aXZpdHkKbGlicmFyeShnZ2FuaW1hdGUpICAgICAjIGZvciBhZGRpbmcgYW5pbWF0aW9uIGxheWVycyB0byBnZ3Bsb3RzCmxpYnJhcnkodHJhbnNmb3JtcikgICAgIyBmb3IgInR3ZWVuaW5nIiAoZ2dhbmltYXRlKQpsaWJyYXJ5KGdpZnNraSkgICAgICAgICMgbmVlZCB0aGUgbGlicmFyeSBmb3IgY3JlYXRpbmcgZ2lmcyBidXQgZG9uJ3QgbmVlZCB0byBsb2FkIGVhY2ggdGltZQpsaWJyYXJ5KGd0KQp0aGVtZV9zZXQodGhlbWVfbWluaW1hbCgpKSAjIE15IGZhdm9yaXRlIGdncGxvdCgpIHRoZW1lIDopCmBgYAoKYGBge3J9CmZyZXFfdGhlbWVfd29yZHMgPC0gcmVhZC5jc3YoImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS90aGUtcHVkZGluZy9kYXRhL21hc3Rlci93b21lbi1pbi1oZWFkbGluZXMvd29yZF90aGVtZXNfZnJlcS5jc3YiKQpmcmVxX2NvdW50cnlfd29yZHMgPC0gcmVhZC5jc3YoImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS90aGUtcHVkZGluZy9kYXRhL21hc3Rlci93b21lbi1pbi1oZWFkbGluZXMvd29yZF9jb3VudHJ5X2ZyZXEuY3N2IikKaGVhZGxpbmVfc2l0ZSA8LSByZWFkLmNzdigiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3RoZS1wdWRkaW5nL2RhdGEvbWFzdGVyL3dvbWVuLWluLWhlYWRsaW5lcy9oZWFkbGluZXNfc2l0ZS5jc3YiKQp3b3JkX3RoZW1lX3JhbmsgPC0gcmVhZC5jc3YoImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS90aGUtcHVkZGluZy9kYXRhL21hc3Rlci93b21lbi1pbi1oZWFkbGluZXMvd29yZF90aGVtZXNfcmFuay5jc3YiKQpoZWFkbGluZV9leGFtcGxlcyA8LSByZWFkLmNzdigiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3RoZS1wdWRkaW5nL2RhdGEvbWFzdGVyL3dvbWVuLWluLWhlYWRsaW5lcy9oZWFkbGluZXMuY3N2IikKcG9sYXJpdHlfc2l0ZSA8LSByZWFkLmNzdigiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3RoZS1wdWRkaW5nL2RhdGEvbWFzdGVyL3dvbWVuLWluLWhlYWRsaW5lcy9wb2xhcml0eV9jb21wYXJpc29uX3NpdGVfY291bnRyeV90aW1lLmNzdiIpCnBvbGFyaXR5X292ZXJfdGltZSA8LSByZWFkLmNzdigiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3RoZS1wdWRkaW5nL2RhdGEvbWFzdGVyL3dvbWVuLWluLWhlYWRsaW5lcy9wb2xhcml0eV9jb21wYXJpc29uX2NvdW50cnlfdGltZS5jc3YiKQpgYGAKClBPTEFSSVRZIENBTENVTEFUSU9OUwpXZSBtZWFzdXJlIHBvbGFyaXR5IGJ5IHBlcmZvcm1pbmcgc2VudGltZW50IGFuYWx5c2lzIG9uIGVhY2ggaGVhZGxpbmUgdXNpbmcgdGhlIFZhZGVyIHB5dGhvbiBwYWNrYWdlLCB3aGVyZSBlYWNoIGhlYWRsaW5lIGdldHMgYSBzZW50aW1lbnQgc2NvcmUgZnJvbSAtMSB0byAxIChmcm9tIG1vcmUgbmVnYXRpdmUgdG8gbW9yZSBwb3NpdGl2ZSkuIEJlY2F1c2Ugd2UgYXJlIGludGVyZXN0ZWQgaW4gcG9sYXJpdHksIHdlIHRha2UgdGhlIGFic29sdXRlIHZhbHVlIG9mIGVhY2ggaGVhZGxpbmUncyBzY29yZS4KCkJJQVMgQ0FMQ1VMQVRJT05TCldlIG1lYXN1cmUgZ2VuZGVyIGJpYXMgYnkgdHJhY2tpbmcgdGhlIGNvbWJpbmVkIG9jY3VycmVuY2Ugb2YgZ2VuZGVyZWQgbGFuZ3VhZ2UgYW5kIHNvY2lhbCBzdGVyZW90eXBlcyB1c3VhbGx5IGFzc29jaWF0ZWQgd2l0aCB3b21lbi4gV2UgZG8gdGhpcyBpbiB0d28gc3RlcHM6CjEpIFdlIGNoZWNrIGlmIGEgaGVhZGxpbmUgY29udGFpbnMgZ2VuZGVyZWQgbGFuZ3VhZ2UgKGkuZS4g4oCcc3Bva2Vzd29tYW4s4oCdIOKAnGNoYWlyd29tYW4s4oCdIOKAnHNoZSzigJ0g4oCcaGVyLOKAnSDigJxicmlkZSzigJ0g4oCcZGF1Z2h0ZXIs4oCdIOKAnGRhdWdodGVycyzigJ0g4oCcZmVtYWxlLOKAnSDigJxmaWFuY2VlLOKAnSDigJxnaXJsLOKAnSDigJxnaXJsZnJpZW5k4oCdIGV0Yy4pLgoyKSBJZiBpdCBjb250YWlucyBnZW5kZXJlZCBsYW5ndWFnZSwgd2UgdGhlbiBjb3VudCB0aGUgbnVtYmVyIG9mIHdvcmRzIHRoYXQgYXJlIGNvbnNpZGVyZWQgdG8gYmUgc29jaWFsIHN0ZXJlb3R5cGVzIGFib3V0IHdvbWVuIChpLmUuIOKAnHdlYWss4oCdIOKAnG1vZGVzdCzigJ0g4oCcdmlyZ2luLOKAnSDigJxzbHV0LOKAnSDigJx3aG9yZSzigJ0g4oCcc2V4eSzigJ0g4oCcZmVtaW5pbmUs4oCdIOKAnHNlbnNpdGl2ZSzigJ0g4oCcZW1vdGlvbmFsLOKAnSDigJxnZW50bGUs4oCdIOKAnHNvZnQs4oCdIOKAnHByZXR0eSzigJ0g4oCcYml0Y2gs4oCdIOKAnHNleHVhbOKAnSBldGMuKS4KRmluYWxseSwgd2Ugbm9ybWFsaXplIHRoaXMgY291bnQgZm9yIGFsbCBoZWFkbGluZXMgd2l0aGluIGVhY2ggb3V0bGV0IGFzIGEgc2NvcmUgYmV0d2VlbiAwIGFuZCAxLCBhbmQgd2UgYWdncmVnYXRlIChpLmUuIGF2ZXJhZ2UpIHRoaXMgc2NvcmUgZm9yIGVhY2ggb3V0bGV0Lgooc2l0ZSBmcm9tIHB1ZGRpbmcgaHR0cHM6Ly9wdWRkaW5nLmNvb2wvMjAyMi8wMi93b21lbi1pbi1oZWFkbGluZXMvKQoKCkEgY3VtdWxhdGl2ZSBiYXIgZ3JhcGggZm9yIHRoZSB3b3JkcyB1c2VkIHRvIGRlc2NyaWJlIHdvbWVuIHVzZWQgaW4gaGVhZGxpbmVzLiBUaGV5IGFyZSBkaXZpZGVkIGludG8gNSBtYWluIGNhdGVnb3JpZXMgd2l0aCBjcmltZSBhbmQgdmlvbGVuY2UgaGF2aW5nIHRoZSBtb3N0IHdvcmRzIGFuZCB0aGUgaGlnaGVzdCBmcmVxdWVuY3kuIFRoZSBncmFwaCBpcyBpbnRlcmFjdGl2ZSBzbyBlYWNoIHdvcmQgY2FuIGJlIGhpZ2hsaWdodGVkIHdpdGggdGhlIGluZGl2aWR1YWwgd29yZCBhbmQgZnJlcXVlbmN5LgoKYGBge3J9CnBpdm90X3dvcmRzIDwtIGZyZXFfdGhlbWVfd29yZHMgJT4lIAogIHBpdm90X2xvbmdlcihjb2xzID0gLXRoZW1lLAogICAgICAgICAgICAgICBuYW1lc190byA9ICJ3b3JkIiwKICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gImZyZXEiKSAlPiUgCiAgbmEub21pdCgpCgp3b3JkX3Bsb3QgPC0gcGl2b3Rfd29yZHMgJT4lIAogIGZpbHRlcih0aGVtZSAhPSAiTm8gdGhlbWUiKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gdGhlbWUsIAogICAgICAgICAgICAgeSA9IGZyZXEsIAogICAgICAgICAgICAgZmlsbCA9IGZjdF9yZW9yZGVyKHdvcmQsIGZyZXEpLAogICAgICAgICAgICAgdGV4dCA9IHBhc3RlKCJ3b3JkOiIsIHdvcmQpKSkgKwogICAgZ2VvbV9jb2woY29sb3IgPSAiYmxhY2siKSArCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsKICAgIHNjYWxlX2ZpbGxfdmlyaWRpc19kKCkrCiAgICBsYWJzKHRpdGxlID0gIkN1bXVsYXRpdmUgRnJlcXVlbmN5IG9mIFdvcmRzIGRlc2NyaWJpbmcgV29tZW4gaW4gSGVhZGxpbmVzIiwKICAgICAgIHggPSAiIiwKICAgICAgIHkgPSAiRnJlcXVlbmN5IikKCmdncGxvdGx5KHdvcmRfcGxvdCwKICAgICAgICAgdG9vbHRpcCA9IGMoInkiLCAidGV4dCIpKQpgYGAKCgpgYGB7cn0KcGl2b3RfY291bnRyeV93b3JkIDwtIGZyZXFfY291bnRyeV93b3JkcyAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSAtY291bnRyeSwKICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAid29yZCIsCiAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJudW1iZXIiKSAlPiUgCiAgZmlsdGVyKHdvcmQgIT0gIlgiKSAlPiUgCiAgbmEub21pdCgpCgpwaXZvdF9jb3VudHJ5X3dvcmQKYGBgCgoKYGBge3J9CndvcmRfdGhlbWVfcmFuayAlPiUgCiAgZmlsdGVyKGByYW5rYCA8IDYpICU+JSAKICBzZWxlY3QoIWBYYCkgJT4lIAogIGdncGxvdChhZXMoeSA9IHdvcmQsIHggPSBjb3VudCkpICsKICBnZW9tX2NvbChhZXMoZmlsbCA9IGNvdW50KSkrCiAgc2NhbGVfZmlsbF92aXJpZGlzX2Mob3B0aW9uID0gInZpcmlkaXMiKSArCiAgZmFjZXRfd3JhcCh+dGhlbWUsCiAgICAgICAgICAgIHNjYWxlcyA9ICJmcmVlIikrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSsKICBsYWJzKHRpdGxlID0gIkNvdW50IG9mIFRvcCA1IHdvcmRzIHBlciBUaGVtZSIsCiAgICAgICB5ID0gIiIsCiAgICAgICB4ID0gIiIpCmBgYAoKClNtb290aCBsaW5lIGdyYXBoIGRpc3BsYXlpbmcgdGhlIGF2ZXJhZ2UgcG9sYXJpdHkgb2YgaGVhZGxpbmVzIG92ZXIgdGltZSB3aXRoIHRoZSB2YWx1ZSBmcm9tIDIwMjAgYmVpbmcgZGlzcGxheWVkIHdpdGggYSBkYXRhIHBvaW50LiBXYW50IHRvIHBsYWNlIHRvcCBsYWJlbCBhYm92ZSBsaW5lIGJ1dCBuZWVkIHRvIGV4cGFuZCBib3VuZHJpZXMgb2YgZ3JhcGghIFdvdWxkIGxpa2UgdG8gYW5pbWF0ZSBvdmVyIHRpbWUsIGlmIHdlIGhhdmUgdGltZS4KCmBgYHtyfQpwb2xhcml0eV9vdmVyX3RpbWUgJT4lIAogIGdyb3VwX2J5KGB5ZWFyYCkgJT4lIAogIHN1bW1hcmlzZSh3b21lbl9tZWFuID0gbWVhbihgd29tZW5fcG9sYXJpdHlfbWVhbmApLAogICAgICAgICAgICBhbGxfbWVhbiA9IG1lYW4oYGFsbF9wb2xhcml0eV9tZWFuYCksCiAgICAgICAgICAgIHllYXIpICU+JSAKICBnZ3Bsb3QoKSsKICBnZW9tX3Ntb290aChhZXMoeD1geWVhcmAsIHk9YHdvbWVuX21lYW5gKSwgY29sb3IgPSAic3ByaW5nZ3JlZW40Iiwgc2UgPSBGQUxTRSkrCiAgZ2VvbV9zbW9vdGgoYWVzKHg9YHllYXJgLCB5PWBhbGxfbWVhbmApLCBjb2xvciA9ICJibGFjayIsIHNlID0gRkFMU0UpKwogIGdlb21fcG9pbnQoYWVzKHg9MjAyMC4wLCB5PTAuNDI1KSwgCiAgICAgICAgICAgICBjb2xvciA9ICJibGFjayIsIGZpbGwgPSAic3ByaW5nZ3JlZW40IiwgCiAgICAgICAgICAgICBzaXplID0gNSwgc3Ryb2tlID0gMiwgc2hhcGUgPSAyMSkgKwogIGdlb21fcG9pbnQoYWVzKHg9MjAyMC4wLCB5PTAuMjgpLCBzaXplID0gMi41KSsKICBnZW9tX2xhYmVsKGxhYmVsID0gIkhlYWRsaW5lcyBhYm91dFxud29tZW4iLCB4PSAyMDE5LjQsIHk9MC40MCwgY29sb3IgPSAic3ByaW5nZ3JlZW40IikrCiAgZ2VvbV9sYWJlbChsYWJlbCA9ICJIZWFkbGluZXMgYWJvdXRcbm90aGVyIHRvcGljcyIsIHg9MjAxOS40LCB5PSAwLjI1KSsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gYygyMDEwLCAyMDEyLCAyMDE0LCAyMDE2LCAyMDE4LCAyMDIwKSkrCiAgbGFicyh0aXRsZSA9ICJBdmVyYWdlIG9mIFBvbGFyaXR5IG9mIE5ld3MgSGVhZGxpbmVzIG92ZXIgVGltZSIsCiAgICAgICB5ID0gIiIsCiAgICAgICB4ID0gIiIpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpLAogICAgICAgIHBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwYW5lbC5ncmlkLm1pbm9yLnggPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBhbmVsLmdyaWQubWlub3IueSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLmxpbmUueCA9IGVsZW1lbnRfbGluZShjb2xvciA9ICJibGFjayIpKQpgYGAKCgoKUG9sYXJpdHkgZnJvbSBzaXRlcywgYmFzZSBwb2xhcml0eSAoYmxhY2spIHRvIHdvbWVuIHBvbGFyaXR5IChncmVlbikgd2l0aCB0aGUgZGlmZmVyZW5jZXMgYXMgYSBsaW5lIHNlZ21lbnQsIHRoZXkgYXJlIG9yZGVyZWQgYnkgcG9sYXJpdHkgb2Ygd29tZW4gdmFsdWUsIG5vdCBieSBkaWZmZXJlbmNlcwoKYGBge3IsIGZpZy5oZWlnaHQ9IDEyLCBmaWcud2lkdGg9IDR9CnBvbGFyaXR5X3NpdGUgJT4lIAogIGdncGxvdCgpKwogIGdlb21fc2VnbWVudChhZXMoeD1wb2xhcml0eV9iYXNlLCB4ZW5kPXBvbGFyaXR5X3dvbWVuLCB5PWZjdF9yZW9yZGVyKHNpdGUsIHBvbGFyaXR5X3dvbWVuKSwgeWVuZD1zaXRlLCBjb2xvciA9IGNvdW50cnlfb2ZfcHViKSwgc2l6ZSA9IDEpKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCJJbmRpYSIgPSAicHVycGxlNCIsCiAgICAgICAgICAgICAgICAgICAgIlNvdXRoIEFmcmljYSIgPSAidGhpc3RsZTMiLAogICAgICAgICAgICAgICAgICAgICJVSyIgPSAic3RlZWxibHVlNCIsCiAgICAgICAgICAgICAgICAgICAgIlVTQSIgPSAibWVkaXVtc2VhZ3JlZW4iKSkrCiAgZ2VvbV9wb2ludChhZXMoeD1wb2xhcml0eV9iYXNlLCB5ID0gc2l0ZSksIHNpemUgPSAyKSsKICBnZW9tX3BvaW50KGFlcyh4PXBvbGFyaXR5X3dvbWVuLCB5ID0gc2l0ZSksIGNvbG9yID0gImJsYWNrIiwgZmlsbCA9ICJzcHJpbmdncmVlbjQiLCAKICAgICAgICAgICAgIHNpemUgPSAzLCBzdHJva2UgPSAxLCBzaGFwZSA9IDIxKSsKICBsYWJzKHRpdGxlID0gIlBvbGFyaXR5IG9mIE5ld3MgT3V0bGluZXM6XG4gSGVhZGxpbmVzIGFib3V0IFdvbWVuIHZzLiBIZWFkbGluZXMgYWJvdXQgb3RoZXIgdG9waWNzIiwKICAgICAgIHkgPSAiIiwKICAgICAgIHggPSAiUG9sYXJpdHkiLAogICAgICAgY29sb3IgPSAiQ291bnRyeSBvZlxuUHVibGljYXRpb24iKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkKYGBgCgoKVGVuIGV4YW1wbGUgaGVhZGxpbmVzIGZyb20gMTAgZGlmZmVyZW50IG5ld3Mgc2l0ZXMsIHNvcnRlZCBieSBsb3dlc3QgYmlhcyBzY29yZQoKYGBge3J9Cmxhc3RfdGVuX2hlYWRsaW5lcyA8LSBoZWFkbGluZV9leGFtcGxlcyAlPiUgCiAgcmVuYW1lKCJIZWFkbGluZSIgPSBgaGVhZGxpbmVfbm9fc2l0ZWAsCiAgICAgICAgICJTaXRlIiA9IGBzaXRlYCwKICAgICAgICAgIkNvdW50cnkiID0gYGNvdW50cnlgLAogICAgICAgICAiQmlhcyIgPSBgYmlhc2ApICU+JQogIGFycmFuZ2UoYEJpYXNgKSAlPiUKICBkaXN0aW5jdChTaXRlLCAua2VlcF9hbGwgPSBUUlVFKSAlPiUgCiAgc2xpY2UoMToxMCkgJT4lIAogIHNlbGVjdChgSGVhZGxpbmVgLCBgU2l0ZWAsIGBDb3VudHJ5YCwgYEJpYXNgKQoKbGFzdF90ZW5faGVhZGxpbmVzX3RhYmxlIDwtIGd0KGxhc3RfdGVuX2hlYWRsaW5lcykgJT4lIAogIHRhYl9oZWFkZXIodGl0bGUgPSAiTGVhc3QgQmlhc2VkIEhlYWRsaW5lIEV4YW1wbGVzIikgJT4lIAogIGRhdGFfY29sb3IoY29sdW1ucyA9IHZhcnMoYEhlYWRsaW5lYCwgYFNpdGVgLCBgQ291bnRyeWAsIGBCaWFzYCksIAogICAgICAgICAgICAgY29sb3JzID0gJyNiY2NhZTAnKQoKbGFzdF90ZW5faGVhZGxpbmVzX3RhYmxlCmBgYAoKClRlbiBleGFtcGxlIGhlYWRsaW5lcyBmcm9tIDEwIGRpZmZlcmVudCBuZXdzIHNpdGVzLCBzb3J0ZWQgYnkgaGlnaGVzdCBiaWFzIHNjb3JlCgpgYGB7cn0KdG9wX3Rlbl9oZWFkbGluZXMgPC0gaGVhZGxpbmVfZXhhbXBsZXMgJT4lIAogIHJlbmFtZSgiSGVhZGxpbmUiID0gYGhlYWRsaW5lX25vX3NpdGVgLAogICAgICAgICAiU2l0ZSIgPSBgc2l0ZWAsCiAgICAgICAgICJDb3VudHJ5IiA9IGBjb3VudHJ5YCkgJT4lIAogIG11dGF0ZShCaWFzID0gcm91bmQoYmlhcywgZGlnaXRzID0gMykpICU+JSAKICBhcnJhbmdlKGRlc2MoYEJpYXNgKSkgJT4lCiAgZGlzdGluY3QoU2l0ZSwgLmtlZXBfYWxsID0gVFJVRSkgJT4lIAogIHNsaWNlKDE6MTApICU+JSAKICBzZWxlY3QoYEhlYWRsaW5lYCwgYFNpdGVgLCBgQ291bnRyeWAsIGBCaWFzYCkKCnRvcF90ZW5faGVhZGxpbmVzX3RhYmxlIDwtIGd0KHRvcF90ZW5faGVhZGxpbmVzKSAlPiUgCiAgdGFiX2hlYWRlcih0aXRsZSA9ICJNb3N0IEJpYXNlZCBIZWFkbGluZSBFeGFtcGxlcyIpICU+JSAKICBkYXRhX2NvbG9yKGNvbHVtbnMgPSB2YXJzKGBIZWFkbGluZWAsIGBTaXRlYCwgYENvdW50cnlgLCBgQmlhc2ApLCAKICAgICAgICAgICAgIGNvbG9ycyA9ICcjYmNjYWUwJykKCnRvcF90ZW5faGVhZGxpbmVzX3RhYmxlCmBgYAoKCgoK